#ifndef cflow_26d839c20f6fd4e674363484c94d5e8f
#define cflow_26d839c20f6fd4e674363484c94d5e8f

#include "base.h"
#include "fcntl.h"

extern "C" {
    #include "ftlib.h"
}

using namespace std;

struct SFlow_smart { /* from smartxac format */
    struct in_addr  ip_src;
    struct in_addr  ip_dst;
    uint8_t     ip_proto;
    uint8_t     ports_ok;
    uint16_t    sport;
    uint16_t    dport;
    uint64_t    pkts;
    uint64_t    bytes;
    uint64_t    flows;
    uint32_t    first_sec;
    uint32_t    first_nsec;
    uint32_t    last_sec;
    uint32_t    last_nsec; 
};

class CFlow {
    public:
    virtual int open( string fname ) {}
    virtual void close() {}
    virtual int next() { }
    virtual int is_ok() { }
    virtual int is_end() { }
    virtual uint64_t getFlows() = 0;
    virtual uint64_t getOctets() = 0;
    virtual uint64_t getPackets() = 0;
    virtual struct in_addr getAddrSrc() = 0;
    virtual struct in_addr getAddrDst() = 0;
    virtual uint16_t getPortSrc() = 0;
    virtual uint16_t getPortDst() = 0;
};

class CFlowSmart : public CFlow {
    private:
    SFlow_smart flowbin;
    FILE * fd;
    int flag_is_ok;
    int sentit;

    private:
    int read_bin2(struct SFlow_smart *a, FILE *fd); 
//    void read_ascii_header(FILE *fd);

    public:
    CFlowSmart();
    

    /* return 1 if read succesfully, 0 otherwise */
//    int read_bin(struct SFlow_smart *a, FILE *fd); 
    int open( string fname ); 
    void close(); 
    int next(); 

    int is_ok();
    int is_end();

    struct in_addr getAddrSrc();
    struct in_addr getAddrDst();
    uint64_t getFlows();
    uint64_t getOctets();
    uint64_t getPackets();
    uint16_t getPortSrc();
    uint16_t getPortDst();
};

class CFlowNF : public CFlow {
    private:
//    SFlow_smart flowbin;
//    FILE * fd;
    int flag_is_ok;
    int flag_end;
//    int sentit;
    struct ftio ftio;
    struct fts3rec_all cur;
    struct fts3rec_offsets fo;
    struct ftver ftv;
    char * rec;
    int fd_in; /* input file FD , stdin default = 0 */

    struct in_addr address_src;
    struct in_addr address_dst;

//    FILE * fd_out; /* output file stream, stdout by default */

    private:
//    int read_bin2(struct SFlow_smart *a, FILE *fd); 
//    void read_ascii_header(FILE *fd);

    public:
    CFlowNF();
    
    /* return 1 if read succesfully, 0 otherwise */
//    int read_bin(struct SFlow_smart *a, FILE *fd); 
    int open( string fname ); 
    void close(); 
    int next(); 

    int is_ok();
    int is_end();

    struct in_addr getAddrSrc();
    struct in_addr getAddrDst();
    uint64_t getFlows();
    uint64_t getOctets();
    uint64_t getPackets();
    uint16_t getPortSrc();
    uint16_t getPortDst();

    uint16_t getAsnSrc();
    uint16_t getAsnDst();
};

#endif // EOF
